// 弹弹球消砖块.cpp : 定义控制台应用程序的入口点。

#include <graphics.h>
#include <conio.h>
#include<time.h>
#include <stdio.h>
#define Width 680
#define High 480
#define Brick_num 10 //游戏砖块的个数


//定义全局变量
int ball_x,ball_y; //小球的坐标
int ball_vx,ball_vy; //小球的速度
int radius; //小球的半径
int bar_x,bar_y; //挡板的中心位置
int bar_height,bar_width; //挡板的高度和宽度
int bar_left,bar_right,bar_top,bar_bottom; //挡板的上下左右位置坐标
int geshu=0; //得分
//砖块
int isBrickExisted[Brick_num]; //每个砖块是否存在,1为存在,0为没有了
int brick_height,brick_width; // 砖块的高度和宽度
int color[Brick_num];
//数据初始化
void initData();
//创建黑色圆圈,防止绿色圆移动的时候带着尾巴.黑色圆就是用来打底(清除痕迹)
void clean();
//画其他颜色的圆
void show();

//与用户输入无关的更新
void updateWithoutInput();

//与用户更新相关的更新
void updateWithInput();

//游戏结束的函数
void gameOver();
int _tmain(int argc, _TCHAR* argv[])
{
	initData();
	while(1){
		clean();
		updateWithoutInput();
		updateWithInput();
		show();
	}
	gameOver();
	return 0;
}

void initData(){
	// rand();
	srand((int)time(0));
	//初始化圆球的信息
	ball_x = rand()%240+200;
	ball_y = rand()%280+100;
	ball_vx = rand()%2+1;
	ball_vy = rand()%2+1;
	radius = 20;
	
	//初始化挡板的信息
	//宽高 和中心坐标
	bar_height = High/20;
	bar_width = Width/5;
	bar_x = Width/2;
	bar_y = High - bar_height/2;
	//上下左右坐标
	bar_left = bar_x - bar_width/2;
	bar_right = bar_x + bar_width/2;
	bar_top = bar_y - bar_height/2;
	bar_bottom = bar_y + bar_height/2;

	//初始化砖块信息
	brick_width = Width/Brick_num;
	brick_height = High/Brick_num;

	int i;
	//设置默认所有砖块都存在
	for(i=0;i<Brick_num;i++){
		isBrickExisted[i] = 1;
		color[i] = rand()%256;
	}
	initgraph(Width,High);
	BeginBatchDraw();
}

void clean() {
	setcolor(BLACK);
	setfillcolor(BLACK);
	fillcircle(ball_x,ball_y,radius);
	bar(bar_left,bar_top,bar_right,bar_bottom);
	int i,brick_left,brick_right,brick_top,brick_bottom;
	for(i = 0;i<Brick_num;i++){
		brick_left = i*brick_width;
		brick_right = brick_left + brick_width;
		brick_top = 0;
		brick_bottom = brick_height;
		//砖块存在,绘制砖块
		if(!isBrickExisted[i]){
			fillrectangle(brick_left,brick_top,brick_right,brick_bottom);
		}
	}
}

void show(){
	setcolor(YELLOW);
	setfillcolor(CYAN);
	fillcircle(ball_x,ball_y,radius);

	setcolor(YELLOW);
	setfillcolor(RED);
	bar(bar_left,bar_top,bar_right,bar_bottom);
	int i,brick_left,brick_right,brick_top,brick_bottom;
	
	for(i = 0;i<Brick_num;i++){
		brick_left = i*brick_width;
		brick_right = brick_left + brick_width;
		brick_top = 0;
		brick_bottom = brick_height;
		//砖块存在,绘制砖块
		if(isBrickExisted[i]){
			setcolor(WHITE);
			setfillcolor(RGB(color[i%4],color[i%5],color[i%6]));			
			fillrectangle(brick_left,brick_top,brick_right,brick_bottom);
		}
	}
	FlushBatchDraw();
	Sleep(10);
}

void updateWithoutInput(){

	//挡板和小球触碰,小球反弹
	if(((ball_y+radius>=bar_top)&&(ball_y+radius<bar_bottom-bar_height/3))
		|| ((ball_y-radius<=bar_bottom)&&(ball_y-radius>bar_top-bar_height/3))
		){
			if((ball_x>=bar_left)&& (ball_x<=bar_right)){
				ball_vy = -ball_vy;
			}
	}

	//判断小球是否和底部接触,如果是则游戏结束,小球停止移动
	if((ball_y+radius*2)==High){
		//// 初始化绘图窗口
		initgraph(640, 480);

		//// 创建 300x300 的 IMAGE 对象，并获取其 HDC 句柄
		IMAGE img(300, 300);
		HDC hdc = GetImageHDC(&img);

		//// 以下是标准Windows GDI操作画一条线（相关语句，请查阅MSDN）
		MoveToEx(hdc, 100, 100, NULL);
		LineTo(hdc, 200, 200);
		//// 标准 Windows GDI 操作结束
	
		//// 将 img 贴到绘图窗口上：
		putimage(0, 0, &img);
		outtextxy(320,240,"游戏结束！  您的分数是：");
		char s[2];
		sprintf(s, "%d", geshu);
		outtextxy(500,240,s);
		//// 按任意键返回
		_getch();
		closegraph();
	}
		
	//更新小圆的坐标
	ball_x = ball_x + ball_vx;
	ball_y = ball_y + ball_vy;
	if((ball_x<=radius)||(ball_x>=Width-radius)){
		ball_vx = -ball_vx;
	}
	if((ball_y<=radius)||(ball_y>=High-radius)){
		ball_vy = -ball_vy;
	}

	//判断小球是否和某个砖块碰撞
	int i,brick_left,brick_right,brick_bottom;
	for(i=0;i<Brick_num;i++){
		if(isBrickExisted[i]){
			brick_left = i*brick_width;
			brick_right = brick_left + brick_width;
			brick_bottom =  brick_height;
			if((ball_y == brick_bottom + radius) && (ball_x>=brick_left) && (ball_x<= brick_right)){
				isBrickExisted[i] = 0;
				ball_vy = -ball_vy;
				geshu +=1;
				if(geshu == 10){
					gameOver();
				}
			}
		}
	}

}

//用户输入处理
void updateWithInput(){
	char input;
	if(_kbhit()){
		input = _getch();
		if(input == 'a' && bar_left>0){
			bar_x = bar_x - 15;
			bar_left = bar_x - bar_width/2;
			bar_right = bar_x + bar_width/2;
		}
		//右移
		if(input == 'd' && bar_right<Width){
			bar_x = bar_x + 15;
			bar_left = bar_x -bar_width/2;
			bar_right = bar_x + bar_width/2;
		}
	}
}

void gameOver(){
	EndBatchDraw();
	closegraph();
}